From 13eb123213626fd441ca335bbefe7fac2e3e8ec7 Mon Sep 17 00:00:00 2001 From: Tim Carey-Smith Date: Thu, 26 Jun 2014 15:14:31 -0700 Subject: [PATCH] Add cargo test --- Makefile | 1 + src/bin/cargo-build.rs | 2 +- src/bin/cargo-test.rs | 60 ++++++++++++++++++++++ src/cargo/core/dependency.rs | 23 +-------- src/cargo/core/manifest.rs | 69 ++++++++++++++++++++++--- src/cargo/core/mod.rs | 6 ++- src/cargo/lib.rs | 11 +++- src/cargo/ops/cargo_compile.rs | 13 +++-- src/cargo/ops/cargo_rustc.rs | 74 +++++++++++++++++++++------ src/cargo/ops/mod.rs | 2 +- src/cargo/sources/git/source.rs | 10 +--- src/cargo/util/hex.rs | 10 ++++ src/cargo/util/mod.rs | 2 + src/cargo/util/process_builder.rs | 2 +- src/cargo/util/toml.rs | 29 +++++++++-- tests/support/mod.rs | 18 +++++++ tests/test_cargo_compile.rs | 19 +------ tests/test_cargo_compile_git_deps.rs | 5 +- tests/test_cargo_compile_path_deps.rs | 4 +- tests/test_cargo_test.rs | 40 +++++++++++++++ tests/tests.rs | 1 + 21 files changed, 310 insertions(+), 91 deletions(-) create mode 100644 src/bin/cargo-test.rs create mode 100644 src/cargo/util/hex.rs create mode 100644 tests/test_cargo_test.rs diff --git a/Makefile b/Makefile index 2e852de1f..dac214192 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ BINS = cargo \ cargo-rustc \ cargo-verify-project \ cargo-git-checkout \ + cargo-test \ SRC = $(shell find src -name '*.rs' -not -path 'src/bin*') diff --git a/src/bin/cargo-build.rs b/src/bin/cargo-build.rs index 8a0f06581..c3d3c96fe 100644 --- a/src/bin/cargo-build.rs +++ b/src/bin/cargo-build.rs @@ -48,7 +48,7 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { let update = options.update_remotes; - ops::compile(&root, update, shell).map(|_| None).map_err(|err| { + ops::compile(&root, update, "compile", shell).map(|_| None).map_err(|err| { CliError::from_boxed(err, 101) }) } diff --git a/src/bin/cargo-test.rs b/src/bin/cargo-test.rs new file mode 100644 index 000000000..8849b2d72 --- /dev/null +++ b/src/bin/cargo-test.rs @@ -0,0 +1,60 @@ +#![crate_id="cargo-test"] +#![feature(phase)] + +#[phase(plugin, link)] +extern crate cargo; +extern crate serialize; + +#[phase(plugin, link)] +extern crate hammer; + +use std::os; +use std::io::fs; + +use cargo::ops; +use cargo::{execute_main_without_stdin}; +use cargo::core::{MultiShell}; +use cargo::util; +use cargo::util::{CliResult, CliError}; +use cargo::util::important_paths::find_project; + +#[deriving(PartialEq,Clone,Decodable)] +struct Options { + manifest_path: Option, + rest: Vec +} + +hammer_config!(Options "Run the package's test suite") + +fn main() { + execute_main_without_stdin(execute); +} + +fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { + let root = match options.manifest_path { + Some(path) => Path::new(path), + None => try!(find_project(os::getcwd(), "Cargo.toml") + .map(|path| path.join("Cargo.toml")) + .map_err(|_| { + CliError::new("Could not find Cargo.toml in this \ + directory or any parent directory", + 102) + })) + }; + + try!(ops::compile(&root, false, "test", shell).map(|_| None::<()>).map_err(|err| { + CliError::from_boxed(err, 101) + })); + + let test_dir = root.dir_path().join("target").join("tests"); + + let mut walk = try!(fs::walk_dir(&test_dir).map_err(|e| { + CliError::from_error(e, 1) + })); + + for file in walk { + try!(util::process(file).exec().map_err(|e| CliError::from_boxed(e.box_error(), 1))); + } + + Ok(None) +} diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 687e49116..6e4c8b25f 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -1,4 +1,3 @@ -use semver::Version; use core::{VersionReq,SourceId}; use util::CargoResult; @@ -10,18 +9,9 @@ pub struct Dependency { } impl Dependency { - pub fn new(name: &str, req: &VersionReq, - namespace: &SourceId) -> Dependency { - Dependency { - name: name.to_str(), - namespace: namespace.clone(), - req: req.clone() - } - } - pub fn parse(name: &str, version: Option<&str>, - namespace: &SourceId) -> CargoResult { - + namespace: &SourceId) -> CargoResult + { let version = match version { Some(v) => try!(VersionReq::parse(v)), None => VersionReq::any() @@ -34,15 +24,6 @@ impl Dependency { }) } - pub fn exact(name: &str, version: &Version, - namespace: &SourceId) -> Dependency { - Dependency { - name: name.to_str(), - namespace: namespace.clone(), - req: VersionReq::exact(version) - } - } - pub fn get_version_req<'a>(&'a self) -> &'a VersionReq { &self.req } diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 21982438d..f9b4c0e18 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -58,7 +58,7 @@ impl> Encodable for Manifest { } } -#[deriving(Show,Clone,PartialEq,Encodable)] +#[deriving(Show, Clone, PartialEq, Hash, Encodable)] pub enum LibKind { Lib, Rlib, @@ -92,17 +92,64 @@ impl LibKind { } } -#[deriving(Show,Clone,PartialEq,Encodable)] +#[deriving(Show, Clone, Hash, PartialEq, Encodable)] pub enum TargetKind { LibTarget(Vec), BinTarget } -#[deriving(Clone,PartialEq)] +#[deriving(Clone, Hash, PartialEq)] +pub struct Profile { + env: String, // compile, test, dev, bench, etc. + opt_level: uint, + debug: bool, + test: bool +} + +impl Profile { + pub fn default(env: &str) -> Profile { + Profile { + env: env.to_str(), // run in the default environment only + opt_level: 0, + debug: true, + test: false // whether or not to pass --test + } + } + + pub fn is_compile(&self) -> bool { + self.env.as_slice() == "compile" + } + + pub fn is_test(&self) -> bool { + self.test + } + + pub fn get_env<'a>(&'a self) -> &'a str { + self.env.as_slice() + } + + pub fn opt_level(mut self, level: uint) -> Profile { + self.opt_level = level; + self + } + + pub fn debug(mut self, debug: bool) -> Profile { + self.debug = debug; + self + } + + pub fn test(mut self, test: bool) -> Profile { + self.test = test; + self + } +} + +#[deriving(Clone, Hash, PartialEq)] pub struct Target { kind: TargetKind, name: String, - path: Path + path: Path, + profile: Profile } #[deriving(Encodable)] @@ -191,19 +238,21 @@ impl Manifest { impl Target { pub fn lib_target(name: &str, crate_targets: Vec, - path: &Path) -> Target { + path: &Path, profile: &Profile) -> Target { Target { kind: LibTarget(crate_targets), name: name.to_str(), - path: path.clone() + path: path.clone(), + profile: profile.clone() } } - pub fn bin_target(name: &str, path: &Path) -> Target { + pub fn bin_target(name: &str, path: &Path, profile: &Profile) -> Target { Target { kind: BinTarget, name: name.to_str(), - path: path.clone() + path: path.clone(), + profile: profile.clone() } } @@ -225,6 +274,10 @@ impl Target { } } + pub fn get_profile<'a>(&'a self) -> &'a Profile { + &self.profile + } + pub fn rustc_crate_types(&self) -> Vec<&'static str> { match self.kind { LibTarget(ref kinds) => { diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index b14bbd6e2..23716f6be 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -6,6 +6,7 @@ pub use self::manifest::{ Manifest, Target, TargetKind, + Profile }; pub use self::package::{ @@ -36,7 +37,10 @@ pub use self::shell::{ ShellConfig }; -pub use self::dependency::Dependency; +pub use self::dependency::{ + Dependency +}; + pub use self::version_req::VersionReq; pub mod errors; diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index ccae60e3a..32a45e48b 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -39,9 +39,18 @@ macro_rules! some( ) ) +// Added so that the try! macro below can refer to cargo::util, while +// other external importers of this macro can use it as well. +// +// "Hygiene strikes again" - @acrichton +mod cargo { + pub use super::util; +} + +#[macro_export] macro_rules! try ( ($expr:expr) => ({ - use util::CargoError; + use cargo::util::CargoError; match $expr.map_err(|err| err.to_error()) { Ok(val) => val, Err(err) => return Err(err) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 308a1146a..9e8b4d4b0 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -24,13 +24,15 @@ use std::os; use util::config::{Config, ConfigValue}; -use core::{MultiShell, Source, SourceId, PackageSet, resolver}; +use core::{MultiShell, Source, SourceId, PackageSet, Target, resolver}; use core::registry::PackageRegistry; use ops; use sources::{PathSource}; use util::{CargoResult, Wrap, config, internal, human}; -pub fn compile(manifest_path: &Path, update: bool, shell: &mut MultiShell) -> CargoResult<()> { +pub fn compile(manifest_path: &Path, update: bool, + env: &str, shell: &mut MultiShell) -> CargoResult<()> +{ log!(4, "compile; manifest-path={}", manifest_path.display()); let mut source = PathSource::for_path(&manifest_path.dir_path()); @@ -60,8 +62,13 @@ pub fn compile(manifest_path: &Path, update: bool, shell: &mut MultiShell) -> Ca debug!("packages={}", packages); + let targets = package.get_targets().iter().filter(|target| { + target.get_profile().get_env() == env + }).collect::>(); + let mut config = try!(Config::new(shell, update)); - try!(ops::compile_packages(&package, &PackageSet::new(packages.as_slice()), &mut config)); + try!(ops::compile_targets(targets.as_slice(), &package, + &PackageSet::new(packages.as_slice()), &mut config)); Ok(()) } diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs index 3357ff886..3411f5306 100644 --- a/src/cargo/ops/cargo_rustc.rs +++ b/src/cargo/ops/cargo_rustc.rs @@ -2,6 +2,8 @@ use std::os::args; use std::io; use std::io::{File, IoError}; use std::str; +use std::hash::sip::SipHasher; +use std::hash::Hasher; use core::{Package, PackageSet, Target}; use util; @@ -19,13 +21,14 @@ struct Context<'a, 'b> { config: &'b mut Config<'b> } -pub fn compile_packages<'a>(pkg: &Package, deps: &PackageSet, - config: &'a mut Config<'a>) -> CargoResult<()> { +pub fn compile_targets<'a>(targets: &[&Target], pkg: &Package, deps: &PackageSet, + config: &'a mut Config<'a>) -> CargoResult<()> { - debug!("compile_packages; pkg={}; deps={}", pkg, deps); + debug!("compile_targets; targets={}; pkg={}; deps={}", targets, pkg, deps); let target_dir = pkg.get_absolute_target_dir(); let deps_target_dir = target_dir.join("deps"); + let tests_target_dir = target_dir.join("tests"); let output = try!(util::process("rustc").arg("-v").exec_with_output()); let rustc_version = str::from_utf8(output.output.as_slice()).unwrap(); @@ -41,6 +44,10 @@ pub fn compile_packages<'a>(pkg: &Package, deps: &PackageSet, internal(format!("Couldn't create the directory for dependencies for {} at {}", pkg.get_name(), deps_target_dir.display())))); + try!(mk_target(&tests_target_dir).chain_error(|| + internal(format!("Couldn't create the directory for tests for {} at {}", + pkg.get_name(), tests_target_dir.display())))); + let mut cx = Context { dest: &deps_target_dir, deps_dir: &deps_target_dir, @@ -52,19 +59,29 @@ pub fn compile_packages<'a>(pkg: &Package, deps: &PackageSet, // Traverse the dependencies in topological order for dep in try!(topsort(deps)).iter() { - try!(compile_pkg(dep, &mut cx)); + let targets = dep.get_targets().iter().filter(|target| { + // Only compile lib targets for dependencies + target.is_lib() && target.get_profile().is_compile() + }).collect::>(); + + try!(compile(targets.as_slice(), dep, &mut cx)); } cx.primary = true; cx.dest = &target_dir; - try!(compile_pkg(pkg, &mut cx)); + + try!(compile(targets, pkg, &mut cx)); Ok(()) } -fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> { +fn compile(targets: &[&Target], pkg: &Package, cx: &mut Context) -> CargoResult<()> { debug!("compile_pkg; pkg={}; targets={}", pkg, pkg.get_targets()); + if targets.is_empty() { + return Ok(()); + } + // First check to see if this package is fresh. // // Note that we're compiling things in topological order, so if nothing has @@ -74,10 +91,12 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> { // // This is not quite accurate, we should only trigger forceful // recompilations for downstream dependencies of ourselves, not everyone - // compiled afterwards. + // compiled afterwards.a + // + // TODO: Figure out how this works with targets let fingerprint_loc = cx.dest.join(format!(".{}.fingerprint", pkg.get_name())); - let (is_fresh, fingerprint) = try!(is_fresh(pkg, &fingerprint_loc, cx)); + let (is_fresh, fingerprint) = try!(is_fresh(pkg, &fingerprint_loc, cx, targets)); if !cx.compiled_anything && is_fresh { try!(cx.config.shell().status("Fresh", pkg)); return Ok(()) @@ -88,6 +107,7 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> { // command if one is present. try!(cx.config.shell().status("Compiling", pkg)); + // TODO: Should this be on the target or the package? match pkg.get_manifest().get_build() { Some(cmd) => try!(compile_custom(pkg, cmd, cx)), None => {} @@ -95,11 +115,8 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> { // After the custom command has run, execute rustc for all targets of our // package. - for target in pkg.get_targets().iter() { - // Only compile lib targets for dependencies - if cx.primary || target.is_lib() { - try!(rustc(&pkg.get_root(), target, cx)) - } + for &target in targets.iter() { + try!(rustc(&pkg.get_root(), target, cx)); } // Now that everything has successfully compiled, write our new fingerprint @@ -111,13 +128,18 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> { } fn is_fresh(dep: &Package, loc: &Path, - cx: &mut Context) -> CargoResult<(bool, String)> { - let new_fingerprint = format!("{}{}", cx.rustc_version, + cx: &mut Context, targets: &[&Target]) -> CargoResult<(bool, String)> +{ + let new_pkg_fingerprint = format!("{}{}", cx.rustc_version, try!(dep.get_fingerprint(cx.config))); + + let new_fingerprint = fingerprint(new_pkg_fingerprint, hash_targets(targets)); + let mut file = match File::open(loc) { Ok(file) => file, Err(..) => return Ok((false, new_fingerprint)), }; + let old_fingerprint = try!(file.read_to_str()); log!(5, "old fingerprint: {}", old_fingerprint); @@ -126,6 +148,17 @@ fn is_fresh(dep: &Package, loc: &Path, Ok((old_fingerprint == new_fingerprint, new_fingerprint)) } +fn hash_targets(targets: &[&Target]) -> u64 { + let hasher = SipHasher::new_with_keys(0,0); + let targets = targets.iter().map(|t| (*t).clone()).collect::>(); + hasher.hash(&targets) +} + +fn fingerprint(package: String, profiles: u64) -> String { + let hasher = SipHasher::new_with_keys(0,0); + util::to_hex(hasher.hash(&(package, profiles))) +} + fn mk_target(target: &Path) -> Result<(), IoError> { io::fs::mkdir_recursive(target, io::UserRWX) } @@ -170,6 +203,7 @@ fn prepare_rustc(root: &Path, target: &Target, crate_types: Vec<&str>, build_base_args(&mut args, target, crate_types, cx); build_deps_args(&mut args, cx); + util::process("rustc") .cwd(root.clone()) .args(args.as_slice()) @@ -184,8 +218,16 @@ fn build_base_args(into: &mut Args, target: &Target, crate_types: Vec<&str>, into.push("--crate-type".to_str()); into.push(crate_type.to_str()); } + + let mut out = cx.dest.clone(); + + if target.get_profile().is_test() { + into.push("--test".to_str()); + out = out.join("tests"); + } + into.push("--out-dir".to_str()); - into.push(cx.dest.display().to_str()); + into.push(out.display().to_str()); } fn build_deps_args(dst: &mut Args, cx: &Context) { diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 456a56ee7..785f77fad 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -1,6 +1,6 @@ pub use self::cargo_compile::compile; pub use self::cargo_read_manifest::{read_manifest,read_package,read_packages}; -pub use self::cargo_rustc::compile_packages; +pub use self::cargo_rustc::compile_targets; mod cargo_compile; mod cargo_read_manifest; diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 97462af20..c126fe2b4 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -2,13 +2,11 @@ use std::fmt::{Show,Formatter}; use std::fmt; use std::hash::Hasher; use std::hash::sip::SipHasher; -use std::io::MemWriter; use std::str; -use serialize::hex::ToHex; use core::source::{Source, SourceId, GitKind, Location, Remote, Local}; use core::{Package,PackageId,Summary}; -use util::{CargoResult,Config}; +use util::{CargoResult, Config, to_hex}; use sources::PathSource; use sources::git::utils::{GitReference,GitRemote,Master,Other}; @@ -81,12 +79,6 @@ fn ident(location: &Location) -> String { format!("{}-{}", ident, to_hex(hasher.hash(&location.to_str()))) } -fn to_hex(num: u64) -> String { - let mut writer = MemWriter::with_capacity(8); - writer.write_le_u64(num).unwrap(); // this should never fail - writer.get_ref().to_hex() -} - impl<'a, 'b> Show for GitSource<'a, 'b> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { try!(write!(f, "git repo at {}", self.remote.get_location())); diff --git a/src/cargo/util/hex.rs b/src/cargo/util/hex.rs new file mode 100644 index 000000000..7512ece21 --- /dev/null +++ b/src/cargo/util/hex.rs @@ -0,0 +1,10 @@ +use std::io::MemWriter; + +use serialize::hex::ToHex; + +pub fn to_hex(num: u64) -> String { + let mut writer = MemWriter::with_capacity(8); + writer.write_le_u64(num).unwrap(); // this should never fail + writer.get_ref().to_hex() +} + diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index a17294cfd..5cc0ccb34 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -5,6 +5,7 @@ pub use self::errors::{CargoResult, CargoError, BoxError, ChainError, CliResult} pub use self::errors::{CliError, FromError, ProcessError}; pub use self::errors::{process_error, internal_error, internal, human}; pub use self::paths::realpath; +pub use self::hex::to_hex; pub mod graph; pub mod process_builder; @@ -14,3 +15,4 @@ pub mod result; pub mod toml; pub mod paths; pub mod errors; +pub mod hex; diff --git a/src/cargo/util/process_builder.rs b/src/cargo/util/process_builder.rs index 1eb7a5f23..772109404 100644 --- a/src/cargo/util/process_builder.rs +++ b/src/cargo/util/process_builder.rs @@ -51,7 +51,7 @@ impl ProcessBuilder { pub fn extra_path(mut self, path: Path) -> ProcessBuilder { // For now, just convert to a string, but we should do something better - self.path.push(path.display().to_str()); + self.path.unshift(path.display().to_str()); self } diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index e9352a140..d8d904330 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -5,7 +5,7 @@ use toml; use url; use core::{SourceId, GitKind}; -use core::manifest::{LibKind, Lib}; +use core::manifest::{LibKind, Lib, Profile}; use core::{Summary, Manifest, Target, Dependency, PackageId}; use core::source::{Location, Local, Remote}; use util::{CargoResult, Require, human}; @@ -66,6 +66,7 @@ pub enum TomlDependency { DetailedDep(DetailedTomlDependency) } + #[deriving(Encodable,Decodable,PartialEq,Clone,Show)] pub struct DetailedTomlDependency { version: Option, @@ -184,28 +185,46 @@ impl TomlManifest { struct TomlTarget { name: String, crate_type: Option>, - path: Option + path: Option, + test: Option } fn normalize(lib: Option<&[TomlLibTarget]>, bin: Option<&[TomlBinTarget]>) -> Vec { log!(4, "normalizing toml targets; lib={}; bin={}", lib, bin); + fn target_profiles(target: &TomlTarget) -> Vec { + let mut ret = vec!(Profile::default("compile")); + + match target.test { + Some(true) | None => ret.push(Profile::default("test").test(true)), + _ => {} + }; + + ret + } + fn lib_targets(dst: &mut Vec, libs: &[TomlLibTarget]) { let l = &libs[0]; let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name)); let crate_types = l.crate_type.clone().and_then(|kinds| { LibKind::from_strs(kinds).ok() }).unwrap_or_else(|| vec!(Lib)); - dst.push(Target::lib_target(l.name.as_slice(), crate_types, - &Path::new(path))); + + for profile in target_profiles(l).iter() { + dst.push(Target::lib_target(l.name.as_slice(), crate_types.clone(), + &Path::new(path.as_slice()), profile)); + } } fn bin_targets(dst: &mut Vec, bins: &[TomlBinTarget], default: |&TomlBinTarget| -> String) { for bin in bins.iter() { let path = bin.path.clone().unwrap_or_else(|| default(bin)); - dst.push(Target::bin_target(bin.name.as_slice(), &Path::new(path))); + + for profile in target_profiles(bin).iter() { + dst.push(Target::bin_target(bin.name.as_slice(), &Path::new(path.as_slice()), profile)); + } } } diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 8b3c296e0..39f5eef86 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -357,3 +357,21 @@ impl Tap for T { pub fn escape_path(p: &Path) -> String { p.display().to_str().as_slice().replace("\\", "\\\\") } + +pub fn basic_bin_manifest(name: &str) -> String { + format!(r#" + [project] + + name = "{}" + version = "0.5.0" + authors = ["wycats@example.com"] + + [[bin]] + + name = "{}" + "#, name, name) +} + +pub static COMPILING: &'static str = " Compiling"; +pub static FRESH: &'static str = " Fresh"; +pub static UPDATING: &'static str = " Updating"; diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 91cb04807..168603d22 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -2,7 +2,8 @@ use std::io::fs; use std::os; use std::path; -use support::{ResultTest, project, execs, main_file, escape_path}; +use support::{ResultTest, project, execs, main_file, escape_path, basic_bin_manifest}; +use support::COMPILING; use hamcrest::{assert_that, existing_file}; use cargo; use cargo::util::{process, realpath}; @@ -10,22 +11,6 @@ use cargo::util::{process, realpath}; fn setup() { } -static COMPILING: &'static str = " Compiling"; - -fn basic_bin_manifest(name: &str) -> String { - format!(r#" - [project] - - name = "{}" - version = "0.5.0" - authors = ["wycats@example.com"] - - [[bin]] - - name = "{}" - "#, name, name) -} - test!(cargo_compile_simple { let p = project("foo") .file("Cargo.toml", basic_bin_manifest("foo").as_slice()) diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs index 052bc7e6e..4af43c06c 100644 --- a/tests/test_cargo_compile_git_deps.rs +++ b/tests/test_cargo_compile_git_deps.rs @@ -2,14 +2,11 @@ use std::io::File; use support::{ProjectBuilder, ResultTest, project, execs, main_file, paths}; use support::{escape_path, cargo_dir}; +use support::{COMPILING, FRESH, UPDATING}; use hamcrest::{assert_that,existing_file}; use cargo; use cargo::util::{ProcessError, process}; -static COMPILING: &'static str = " Compiling"; -static FRESH: &'static str = " Fresh"; -static UPDATING: &'static str = " Updating"; - fn setup() { } diff --git a/tests/test_cargo_compile_path_deps.rs b/tests/test_cargo_compile_path_deps.rs index 635808eb1..25bbf0df9 100644 --- a/tests/test_cargo_compile_path_deps.rs +++ b/tests/test_cargo_compile_path_deps.rs @@ -2,6 +2,7 @@ use std::io::File; use std::io::timer; use support::{ResultTest, project, execs, main_file, escape_path, cargo_dir}; +use support::{COMPILING, FRESH}; use hamcrest::{assert_that, existing_file}; use cargo; use cargo::util::{process}; @@ -9,9 +10,6 @@ use cargo::util::{process}; fn setup() { } -static COMPILING: &'static str = " Compiling"; -static FRESH: &'static str = " Fresh"; - test!(cargo_compile_with_nested_deps_shorthand { let p = project("foo") .file("Cargo.toml", r#" diff --git a/tests/test_cargo_test.rs b/tests/test_cargo_test.rs new file mode 100644 index 000000000..ad47932e2 --- /dev/null +++ b/tests/test_cargo_test.rs @@ -0,0 +1,40 @@ +use support::{project, execs, basic_bin_manifest, COMPILING}; +use hamcrest::{assert_that, existing_file}; +use cargo::util::process; + +fn setup() {} + +test!(cargo_test_simple { + let p = project("foo") + .file("Cargo.toml", basic_bin_manifest("foo").as_slice()) + .file("src/foo.rs", r#" + fn hello() -> &'static str { + "hello" + } + + pub fn main() { + println!("{}", hello()) + } + + #[test] + fn test_hello() { + assert_eq!(hello(), "hello") + }"#); + + assert_that(p.cargo_process("cargo-build"), execs()); + assert_that(&p.bin("foo"), existing_file()); + + assert_that( + process(p.bin("foo")), + execs().with_stdout("hello\n")); + + assert_that(p.cargo_process("cargo-test"), + execs().with_stdout(format!("{} foo v0.5.0 (file:{})\n\n\ + running 1 test\n\ + test test_hello ... ok\n\n\ + test result: ok. 1 passed; 0 failed; \ + 0 ignored; 0 measured\n\n", + COMPILING, p.root().display()))); + + assert_that(&p.bin("tests/foo"), existing_file()); +}) diff --git a/tests/tests.rs b/tests/tests.rs index 1e99363fc..6dd3bb280 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -23,4 +23,5 @@ macro_rules! test( mod test_cargo_compile; mod test_cargo_compile_git_deps; mod test_cargo_compile_path_deps; +mod test_cargo_test; mod test_shell; -- 2.30.2